﻿using Fiddler;
using Newtonsoft.Json.Linq;
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace FiddlerExUtils.Helper
{
    public class HttpRequestHelper
    {
        //加解密表单信息
        private static string VIEWSTATE = "";
        private static string VIEWSTATEGENERATOR = "";
        private static string EVENTVALIDATION = "";

        /// <summary>
        /// 是否更新表单信息
        /// </summary>
        private static bool updatedFormInfo = false; //保留老加解密字段

        /// <summary>
        /// 获取表单信息,type: 1 加解密； 2 通用接口提交数据
        /// </summary>
        /// <param name="decryptUrl"></param>
        private static bool GetFormInfo(string url)
        {
            if (!updatedFormInfo)
            {
                //MessageBox.Show("已启用备用加解密地址");
                try
                {
                    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
                    req.Method = "POST";
                    req.ContentType = "application/x-www-form-urlencoded";
                    req.Timeout = FiddlerApplication.Prefs.GetInt32Pref("fiddlerex.func.timeout", 1000);
                    req.Proxy = null;

                    #region 添加Post 参数

                    byte[] data = Encoding.UTF8.GetBytes("");

                    req.ContentLength = data.Length;
                    using (Stream reqStream = req.GetRequestStream())
                    {
                        reqStream.Write(data, 0, data.Length);
                        reqStream.Close();
                    }

                    #endregion

                    HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
                    Stream stream = resp.GetResponseStream();
                    //获取响应内容  
                    using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
                    {
                        string input = reader.ReadToEnd();
                        string[] resultString = Regex.Split(input, "name=\"__VIEWSTATE\"", RegexOptions.IgnoreCase);

                        foreach (string result in resultString)
                        {
                            if (result.Contains("id=\"__VIEWSTATE\""))
                            {
                                VIEWSTATE = Regex.Unescape(result.Split('"')[3]);
                            }
                        }

                        resultString = Regex.Split(input, "name=\"__VIEWSTATEGENERATOR\"", RegexOptions.IgnoreCase);

                        foreach (string result in resultString)
                        {
                            if (result.Contains("id=\"__VIEWSTATEGENERATOR\""))
                            {
                                VIEWSTATEGENERATOR = Regex.Unescape(result.Split('"')[3]);
                            }
                        }

                        resultString = Regex.Split(input, "name=\"__EVENTVALIDATION\"", RegexOptions.IgnoreCase);

                        foreach (string result in resultString)
                        {
                            if (result.Contains("id=\"__EVENTVALIDATION\""))
                            {
                                EVENTVALIDATION = Regex.Unescape(result.Split('"')[3]);
                            }
                        }
                    }

                    updatedFormInfo = true;
                    return true;
                }
                catch (Exception ex)
                {
                    updatedFormInfo = false;
                    FiddlerApplication.Log.LogString("GetFormInfo：" + ex.StackTrace);
                    return false;
                }
            }
            updatedFormInfo = true;
            return true;
        }
        /// <summary>
        /// 备用加密方法
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public static string GetBackupEncResponse(string content)
        {
            string url = FiddlerApplication.Prefs.GetStringPref("fiddlerex.urlconfig.backupdecrypturl", "");
            if (GetFormInfo(url))
            {
                try
                {
                    string result = "";
                    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
                    req.Method = "POST";
                    req.ContentType = "application/x-www-form-urlencoded";
                    req.Timeout = FiddlerApplication.Prefs.GetInt32Pref("fiddlerex.func.timeout", 1000);
                    req.Proxy = null;

                    #region 添加Post 参数

                    byte[] data = Encoding.UTF8.GetBytes("__VIEWSTATE=" + Utilities.UrlEncode(VIEWSTATE) + "&__VIEWSTATEGENERATOR=" + Utilities.UrlEncode(VIEWSTATEGENERATOR) + "&__EVENTVALIDATION="
                        + Utilities.UrlEncode(EVENTVALIDATION) + "&txtCode="
                        + Utilities.UrlEncode(content)
                        + "&txtEncryptCode=&btnEncrypt=%e5%8a%a0%e5%af%86&txtDecryptCode="
                        );
                    req.ContentLength = data.Length;
                    using (Stream reqStream = req.GetRequestStream())
                    {
                        reqStream.Write(data, 0, data.Length);
                        reqStream.Close();
                    }

                    #endregion

                    HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
                    Stream stream = resp.GetResponseStream();
                    //获取响应内容  
                    using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
                    {
                        result = reader.ReadToEnd();
                    }
                    //MessageBox.Show(result);
                    string[] resultString = Regex.Split(result, "textarea", RegexOptions.IgnoreCase);
                    foreach (string res in resultString)
                    {
                        if (res.Contains("id=\"txtEncryptCode\""))
                        {
                            string re = Regex.Unescape(res.Split('>')[1].Split('<')[0].Replace("&quot;", "\"").Replace("&#165;", "¥").Replace("&#183;", "·")).Trim();
                            return (re != "" ? re : content);
                        }
                    }
                    return content;

                }
                catch (Exception ex)
                {
                    FiddlerApplication.Log.LogString("GetBackupEncResponse：" + ex.StackTrace);
                    return content;
                }
            }
            return content;
        }
        /// <summary>
        /// 备用解密方法
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public static string GetBackupDecResponse(string content)
        {
            string url = FiddlerApplication.Prefs.GetStringPref("fiddlerex.urlconfig.backupdecrypturl", "");
            if (GetFormInfo(url))
            {
                try
                {
                    string result = "";
                    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
                    req.Method = "POST";
                    req.ContentType = "application/x-www-form-urlencoded";
                    req.Timeout = FiddlerApplication.Prefs.GetInt32Pref("fiddlerex.func.timeout", 1000);
                    req.Proxy = null;

                    #region 添加Post 参数

                    byte[] data = Encoding.UTF8.GetBytes("__VIEWSTATE=" + Utilities.UrlEncode(VIEWSTATE) + "&__VIEWSTATEGENERATOR=" + Utilities.UrlEncode(VIEWSTATEGENERATOR) + "&__EVENTVALIDATION="
                        + Utilities.UrlEncode(EVENTVALIDATION) + "&txtCode=&txtEncryptCode="
                        + Utilities.UrlEncode(content)
                        + "&Button1=%E8%A7%A3%E5%AF%86&txtDecryptCode="
                        );
                    req.ContentLength = data.Length;
                    using (Stream reqStream = req.GetRequestStream())
                    {
                        reqStream.Write(data, 0, data.Length);
                        reqStream.Close();
                    }

                    #endregion

                    HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
                    Stream stream = resp.GetResponseStream();
                    //获取响应内容  
                    using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
                    {
                        result = reader.ReadToEnd();
                    }
                    //MessageBox.Show(result);
                    string[] resultString = Regex.Split(result, "textarea", RegexOptions.IgnoreCase);
                    foreach (string res in resultString)
                    {
                        if (res.Contains("id=\"txtDecryptCode\""))
                        {
                            string re = ReplaceSpecialString(Regex.Unescape(res.Split('>')[1].Split('<')[0].Replace("&quot;", "\"").Replace("&#165;", "¥").Replace("&#183;", "·")).Replace("&lt;", "<").Replace("&gt;", ">").Trim());
                            return (re != "" ? re : content);
                        }
                    }
                    return content;

                }
                catch (Exception ex)
                {
                    FiddlerApplication.Log.LogString("GetBackupDecResponse：" + ex.StackTrace);
                    return content;
                }
            }
            return content;
        }

        /// <summary>
        /// 替换表情等不识别字符
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private static string ReplaceSpecialString(string str)
        {
            string result = Regex.Replace(str, @"\p{Cs}", "");
            //result = this.JsonPre(result);
            return result;
        }

        public static string GetHttpResponse(string requestMethod, JObject paramObj, string requestUrl)
        {
            string result = "";
            try
            {
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(requestUrl);
                req.Method = requestMethod;
                req.ContentType = "application/json";
                req.Timeout = FiddlerApplication.Prefs.GetInt32Pref("fiddlerex.func.timeout", 1000);
                req.Proxy = null;

                #region 添加Post 参数
                paramObj.Add("token", FiddlerApplication.Prefs.GetStringPref("fiddlerex.func.blackstone.token", ""));
                byte[] data = Encoding.UTF8.GetBytes(paramObj.ToString());
                req.ContentLength = data.Length;
                using (Stream reqStream = req.GetRequestStream())
                {
                    reqStream.Write(data, 0, data.Length);
                    reqStream.Close();
                }

                #endregion
                //FiddlerApplication.Log.LogString(paramObj.ToString() + " \r\nStart:" + DateTime.Now);
                HttpWebResponse resp = (HttpWebResponse)req.GetResponse();

                //获取响应内容  
                Stream stream = resp.GetResponseStream();
                using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
                {
                    result = reader.ReadToEnd();
                }
                resp.Close();
                //FiddlerApplication.Log.LogString(paramObj.ToString() + " \r\nEnd:" + DateTime.Now);
            }
            catch (Exception ex)
            {
                FiddlerApplication.Log.LogString("GetHttpResponse：" + requestUrl + "\r\n请求：" + paramObj.ToString());   //TODO
            }
            return result;
        }
    }
}
